﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __E1D1DF14_D2AD_45DC_9579_B26648903C66__
#define __E1D1DF14_D2AD_45DC_9579_B26648903C66__

// 
// mac headers
// 
#include <unistd.h>  
#include <dirent.h> 
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/event.h>
#include <errno.h>
#include <dlfcn.h> // dlopen、dlsym、dlerror、dlclose的头文件

#include <mach-o/dyld.h>
#include <signal.h>

namespace xos_helper
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // xos_strcpy
    // 
    static void xos_strcpy( char * lpszDest, const char * lpszSrc )
    {
        strcpy( lpszDest, lpszSrc );
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // xos_strcat
    // 
    static void xos_strcat( char * lpszDest, const char * lpszSrc )
    {
        strcat( lpszDest, lpszSrc );
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // xos_path_append
    // 
    static int xos_path_append( char * lpszPath, const char * lpszAdder )
    {
        int nRet = 0;

        size_t tLen = strlen( lpszPath );

        if( 0 == nRet )
        {
            if( ( tLen > 0 ) && ( *( lpszPath + tLen ) != '/' ) )
            {
                strcat( lpszPath, "/" );
            }

            strcat( lpszPath, lpszAdder );
        }

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // get process full file name
    // 
    static int xos_get_process_file_full_name( char * pszFile, int nLen, int * pnLenNeeded )
    {
        int nRet = 0;

        char szFile[4096] = { 0 };
        int len = 0;

        uint32_t tLen = sizeof( szFile ) / sizeof( szFile[0] );
        _NSGetExecutablePath( szFile, &tLen );

        len = strlen( szFile ) + 1;

        if( pszFile && ( nLen > len ) )
        {
            strcpy( pszFile, szFile );
        }

        if( pnLenNeeded )
        {
            *pnLenNeeded = len + 1;
        }

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // get process file path. including '\\' or '/'
    //
    static int xos_get_process_path( char * pszPath, int nLen, int * pnLenNeeded )
    {
        int nRet = 0;

        char szFile[4096] = { 0 };

        xos_get_process_file_full_name( szFile, sizeof( szFile ) / sizeof( szFile[0] ), 0 );

        char * p = 0, * pp = szFile;

        while( *pp != 0 )
        {
            if( *pp == '/' )
            {
                p = pp;
            }

            ++pp;
        }

        if( p )
        {
            *p = 0;
        }

        int len = ( int )strlen( szFile );

        if( pnLenNeeded )
        {
            *pnLenNeeded = len;
        }

        if( pszPath && ( nLen > len ) )
        {
            strcpy( pszPath, szFile );
        }
        else
        {
            nRet = 1;
        }

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // xos_load
    // 
    static int xos_load( const char * lpszFile, void* & pModule )
    {
        using namespace std;
        int nRet = 0;

        ////////////////////////////////////////////////////////////
        // 载入DLL

        if( 0 == nRet )
        {
            pModule = dlopen( lpszFile, RTLD_LAZY );

            if( !pModule )
            {
                cout << "module is null" << endl;
                cout << "error = " << dlerror() << endl;
                nRet = 1;
            }
        }

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // xos_free
    // 
    static int xos_free( void* & pModule )    
    {
        int nRet = 0;

        if( pModule )
        {
            dlclose( pModule );
            pModule = 0;
        }

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // xos_get_proc_by_name
    //
    static int xos_get_proc_by_name( void ** ppv, void * pModule, const char * lpszProcName )
    {
        void * pRet = 0;
        int nRet = 0;

        if( 0 == nRet )
        {
            if( !lpszProcName || ( 0 == strlen( lpszProcName ) ) )
            {
                nRet = 1;
            }
        }

        if( 0 == nRet )
        {
            pRet = dlsym( pModule, lpszProcName );
            if( !pRet )
            {
                nRet = 1;
            }
        }

        if( 0 == nRet )
        {
            *ppv = pRet;
        }

        return nRet;
    }

} // xos_helper

#endif // __E1D1DF14_D2AD_45DC_9579_B26648903C66__
